﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace BenevolentSun
{
    public class HorizontalMenuControl : TextMenu
    {

        Dictionary<TextField, Tween> alphaTweens = new Dictionary<TextField, Tween>();
        Dictionary<TextField, Tween> vertTweens = new Dictionary<TextField, Tween>();
        Dictionary<TextField, Tween> scaleTweens = new Dictionary<TextField, Tween>();

        Sprite light;

        Sprite spotlight;

        Tween lightAlphaTween;

        Tween lightXTween;


        public HorizontalMenuControl(ContentManager content)
            : base()
        {
            light = new Sprite(content.Load<Texture2D>("Textures/Gui/Horizontal Menu Light"));
            light.CalcOrigin(0.5f, 0f);

            spotlight = new Sprite(content.Load<Texture2D>("Textures/Gui/Horizontal Menu Spotlight"));
            spotlight.CalcOrigin(0.5f, 0f);
            spotlight.Position.Y = 540f;
        }


        public void Initialize()
        {
            selectedIndex = 0;


            foreach (TextField tf in Entries)
                tf.AlignH = AlignH.Center;
            Entries[0].AlignH = AlignH.Left;
            Entries[Entries.Count - 1].AlignH = AlignH.Right;
            DistributeX(50, 1280 - 50);


            foreach (TextField tf in Entries)
                TweenEntryOut(tf);
            TweenEntryIn(Selected);

            /*
            foreach (TextField tf in alphaTweens.Keys)
            {
                alphaTweens[tf].AdvanceToEnd();
                tf.Color.A = (byte)alphaTweens[tf].Value;
            }
            alphaTweens.Clear();

            foreach (TextField tf in scaleTweens.Keys)
            {
                scaleTweens[tf].AdvanceToEnd();
                tf.Scale = new Vector2(scaleTweens[tf].Value, scaleTweens[tf].Value);
            }
            scaleTweens.Clear();

            foreach (TextField tf in vertTweens.Keys)
            {
                vertTweens[tf].AdvanceToEnd();
                tf.Position = new Vector2(tf.Position.X, vertTweens[tf].Value);
            }
            vertTweens.Clear();
            vertTweens[Selected] = new Tween(Selected.Position.Y, Selected.Position.Y + 6, 0.5, Tween.LoopType.Oscillate);

            //lightAlphaTween.AdvanceToEnd();
            lightXTween.AdvanceToEnd();
            light.Position.X = lightXTween.Value;
            light.Color = new Color(Selected.Color.ToVector3());
            light.Color.A = 0;// (byte)lightAlphaTween.Value;

            spotlight.Position.X = lightXTween.Value;
            spotlight.Color = new Color(Selected.Color.ToVector3());
            spotlight.Color.A = 0;// (byte)lightAlphaTween.Value;

            lightAlphaTween = null;
            lightXTween = null;
            */

            AdvanceToEnd();

            foreach (TextField tf in Entries)
                tf.Color.A = 0;
        }

        public void AdvanceToEnd()
        {
            foreach (TextField tf in Entries)
                TweenEntryOut(tf);
            TweenEntryIn(Selected);

            foreach (TextField tf in alphaTweens.Keys)
            {
                alphaTweens[tf].AdvanceToEnd();
                tf.Color.A = (byte)alphaTweens[tf].Value;
            }
            alphaTweens.Clear();

            foreach (TextField tf in scaleTweens.Keys)
            {
                scaleTweens[tf].AdvanceToEnd();
                tf.Scale = new Vector2(scaleTweens[tf].Value, scaleTweens[tf].Value);
            }
            scaleTweens.Clear();

            foreach (TextField tf in vertTweens.Keys)
            {
                vertTweens[tf].AdvanceToEnd();
                tf.Position = new Vector2(tf.Position.X, vertTweens[tf].Value);
            }
            vertTweens.Clear();
            vertTweens[Selected] = new Tween(Selected.Position.Y, Selected.Position.Y + 6, 0.5, Tween.LoopType.Oscillate);

            light.Color = new Color(Selected.Color.ToVector3());
            light.Color.A = 0;
            spotlight.Color = new Color(Selected.Color.ToVector3());
            spotlight.Color.A = 0;

            if (lightXTween != null)
            {
                lightXTween.AdvanceToEnd();
                light.Position.X = lightXTween.Value;

                spotlight.Position.X = lightXTween.Value;
            }

            if (lightAlphaTween != null)
            {
                lightAlphaTween.AdvanceToEnd();
                
                light.Color.A = (byte)lightAlphaTween.Value;
                spotlight.Color.A = (byte)lightAlphaTween.Value;
            }

            lightAlphaTween = null;
            lightXTween = null;
        }


        public override bool Next(bool rollover)
        {
            TextField old = Selected;
            bool changed = base.Next(rollover);
            if (changed)
            {
                TweenEntryIn(Selected);
                TweenEntryOut(old);
            }
            return changed;
        }

        public override bool Prev(bool rollover)
        {
            TextField old = Selected;
            bool changed = base.Prev(rollover);
            if (changed)
            {
                TweenEntryIn(Selected);
                TweenEntryOut(old);
            }
            return changed;
        }


        public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {
            Dictionary<TextField, Tween> alphaTweens = new Dictionary<TextField, Tween>(this.alphaTweens);
            foreach (TextField tf in alphaTweens.Keys)
            {
                alphaTweens[tf].Update(gameTime);
                tf.Color.A = (byte)alphaTweens[tf].Value;
                if (alphaTweens[tf].IsFinished)
                {
                    this.alphaTweens.Remove(tf);
                }
            }

            Dictionary<TextField, Tween> scaleTweens = new Dictionary<TextField, Tween>(this.scaleTweens);
            foreach (TextField tf in scaleTweens.Keys)
            {
                scaleTweens[tf].Update(gameTime);
                tf.Scale = new Vector2(scaleTweens[tf].Value, scaleTweens[tf].Value);
                if (scaleTweens[tf].IsFinished)
                {
                    this.scaleTweens.Remove(tf);
                }
            }

            Dictionary<TextField, Tween> vertTweens = new Dictionary<TextField, Tween>(this.vertTweens);
            foreach (TextField tf in vertTweens.Keys)
            {
                vertTweens[tf].Update(gameTime);
                tf.Position = new Vector2(tf.Position.X, vertTweens[tf].Value);
                if (vertTweens[tf].IsFinished)
                {
                    this.vertTweens.Remove(tf);
                    if (tf == Selected)
                    {
                        this.vertTweens[tf] = new Tween(tf.Position.Y, tf.Position.Y + 6, 0.5, Tween.LoopType.Oscillate);
                    }
                }
            }

            if (lightAlphaTween != null)
            {
                lightAlphaTween.Update(gameTime);
                light.Color.A = (byte)lightAlphaTween.Value;
                spotlight.Color.A = (byte)lightAlphaTween.Value;
                if (lightAlphaTween.IsFinished)
                    lightAlphaTween = null;
            }

            if (lightXTween != null)
            {
                lightXTween.Update(gameTime);
                light.Position = new Vector2(lightXTween.Value, light.Position.Y);
                spotlight.Position = new Vector2(lightXTween.Value, spotlight.Position.Y);
                if (lightXTween.IsFinished)
                    lightXTween = null;
            }

            base.Update(gameTime);
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            base.Draw(spriteBatch);
            light.Draw(spriteBatch);
            spotlight.Draw(spriteBatch);
        }


        private void TweenEntryIn(TextField tf)
        {
            alphaTweens[tf] = new Tween(tf.Color.A, 255, 0.2, Tween.LoopType.None);
            vertTweens[tf] = new Tween(tf.Position.Y, 376 + 10, 0.2, Tween.LoopType.None);
            scaleTweens[tf] = new Tween(tf.Scale.X, 1.6f, 0.2, Tween.LoopType.None);

            if (tf.AlignH == AlignH.Center)
                lightXTween = new Tween(light.Position.X, tf.Position.X, 0.2, Tween.LoopType.None);
            else if (tf.AlignH == AlignH.Left)
                lightXTween = new Tween(light.Position.X, tf.Position.X + tf.TextDimensions.X * 1.6f / 2f, 0.2, Tween.LoopType.None);
            else if (tf.AlignH == AlignH.Right)
                lightXTween = new Tween(light.Position.X, tf.Position.X - tf.TextDimensions.X * 1.6f / 2f, 0.2, Tween.LoopType.None);
            light.Color = new Color(tf.Color.ToVector3());
            spotlight.Color = new Color(tf.Color.ToVector3());
        }

        private void TweenEntryOut(TextField tf)
        {
            alphaTweens[tf] = new Tween(tf.Color.A, 80, 0.2, Tween.LoopType.None);
            vertTweens[tf] = new Tween(tf.Position.Y, 442 + 5, 0.2, Tween.LoopType.None);
            scaleTweens[tf] = new Tween(tf.Scale.X, 1f, 0.2, Tween.LoopType.None);
        }


        public void FadeIn()
        {
            foreach (TextField tf in Entries)
            {
                if (tf == Selected)
                    alphaTweens[tf] = new Tween(tf.Color.A, 255, 0.25, Tween.LoopType.None);
                else
                    alphaTweens[tf] = new Tween(tf.Color.A, 80, 0.25, Tween.LoopType.None);
            }

            lightAlphaTween = new Tween(light.Color.A, 255, 0.25, Tween.LoopType.None);
        }

        public void FadeOut()
        {
            foreach (TextField tf in Entries)
            {
                if (tf == Selected)
                    alphaTweens[tf] = new Tween(tf.Color.A, 0, 0.25, Tween.LoopType.None);
                else
                    alphaTweens[tf] = new Tween(tf.Color.A, 0, 0.25, Tween.LoopType.None);
            }

            lightAlphaTween = new Tween(light.Color.A, 0f, 0.25, Tween.LoopType.None);
        }

        public Boolean IsFading
        {
            get
            {
                return (lightAlphaTween != null);
            }
        }

        public float FadeValue
        {
            get
            {
                return light.Color.A;
            }
        }
    }
}
